﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PACKETPARSERMAX20.CORE
{
    public static class ReaderExtensions
    {
        public static string BytesDump(this byte[] bytes)
        {
            string t = "";
            foreach (byte tbyte in bytes)
            {
                t += "\r\n" + tbyte.ToString();
            }
            return t;
        }

        public static UInt64 popGuid(this byte[] bytes, int pIndex)
        {
            byte[] tGUID;
            popGuid(bytes, pIndex, out tGUID);
            return BitConverter.ToUInt64(tGUID, 0);
        }

        public static void popGuid(this byte[] bytes, int pIndex, out byte[] pGUI)
        {
            pGUI = new byte[8];
            if (pIndex > bytes.Length) { return; }
            byte mask = bytes[pIndex];

            byte compSize = 0;
            byte tmpMask = 1;

            int j = pIndex + 1;
            for (byte i = 0; i < 8; i++)
            {
                if ((mask & tmpMask) > 0)
                {
                    compSize++;
                    if (j > bytes.Length) { break; }
                    byte tmp = bytes[j];
                    j++;
                    pGUI[i] = tmp;
                }
                tmpMask *= 2;
            }
        }

        public static string FloatDump(this System.IO.BinaryReader reader, int count)
        {

            long tposition = reader.BaseStream.Position;
            byte[] tbytes = reader.ReadBytes(count);
            string ttext = tbytes.FloatDump();
            reader.BaseStream.Position = tposition;
            return ttext;
        }

        public static string FloatDump(this byte[] bytes)
        {
            string ttext = "";
            for (int j = 0; j < bytes.Length; j++)
            {
                ttext += j.ToString();
                if ((bytes.Length - j) >= 4)
                {
                    float tdump = BitConverter.ToSingle(bytes, j);
                    ttext += "\t" + tdump.ToString() + "\r\n";
                }
            }
            System.Diagnostics.Debug.WriteLine(ttext);

            return ttext;
        }

        public static string ValuesDump(this System.IO.BinaryReader reader, int count)
        {
            long tposition = reader.BaseStream.Position;
            byte[] tbytes = reader.ReadBytes(count);

            string tByte = "";
            string tInt16 = "";
            string tUInt16 = "";
            string tInt32 = "";
            string tUInt32 = "";
            string tfloat = "";
            string tInt64 = "";
            string tUInt64 = "";
            for (int j = 0; j < count; j++)
            {

                if ((tbytes.Length - j) >= 1)
                {
                    tByte += j.ToString() + "\tBYTE: " + tbytes[j].ToString() + "\r\n";
                }

                if ((tbytes.Length - j) >= 2)
                {
                    tInt16 += j.ToString() + "\tInt16: " + BitConverter.ToInt16(tbytes, j).ToString() + "\r\n";
                    tUInt16 += j.ToString() + "\tUInt16: " + BitConverter.ToUInt16(tbytes, j).ToString() + "\r\n";
                }

                if ((tbytes.Length - j) >= 4)
                {
                    tInt32 += j.ToString() + "\tInt32: " + BitConverter.ToInt32(tbytes, j).ToString() + "\r\n";
                    tUInt32 += j.ToString() + "\tUInt32: " + BitConverter.ToUInt32(tbytes, j).ToString() + "\r\n";
                    tfloat += j.ToString() + "\tfloat: " + BitConverter.ToSingle(tbytes, j).ToString() + "\r\n";
                }
                if ((tbytes.Length - j) >= 8)
                {
                    tInt64 += j.ToString() + "\tInt64: " + BitConverter.ToInt64(tbytes, j).ToString() + "\r\n";
                }

                if ((tbytes.Length - j) >= 8)
                {
                    tUInt64 += j.ToString() + "\tUInt64: " + BitConverter.ToUInt64(tbytes, j).ToString() + "\r\n";
                }
            }

            System.Diagnostics.Debug.WriteLine(tByte);
            System.Diagnostics.Debug.WriteLine(tInt16); ;
            System.Diagnostics.Debug.WriteLine(tUInt16);
            System.Diagnostics.Debug.WriteLine(tInt32);
            System.Diagnostics.Debug.WriteLine(tUInt32);
            System.Diagnostics.Debug.WriteLine(tfloat);
            System.Diagnostics.Debug.WriteLine(tInt64);
            System.Diagnostics.Debug.WriteLine(tUInt64);

            string tResult = tByte + "\r\n" +
                tInt16 + "\r\n" +
                    tUInt16 + "\r\n" +
                        tInt32 + "\r\n" +
                            tUInt32 + "\r\n" +
                                tfloat + "\r\n" +
                                    tInt64 + "\r\n" +
                                        tUInt64 + "\r\n";

            reader.BaseStream.Position = tposition;
            return tResult;
        }

        public static string ToHexDump(this byte[] arr, string pOpcodeName, uint opcode, int start, int count, int Direction)
        {
            StringBuilder hexDump = new StringBuilder();

            hexDump.AppendLine();
            hexDump.AppendLine(string.Format("{0} ({1}) Packet: (0x{2}) ({3}) {4} PacketSize = {5}", ((Direction)Direction).ToString(), Direction, (opcode).ToString("X4"), opcode, pOpcodeName, count));
            hexDump.AppendLine("|------------------------------------------------|----------------|");
            hexDump.AppendLine("|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|");
            hexDump.AppendLine("|------------------------------------------------|----------------|");

            int end = start + count;
            for (int i = start; i < end; i += 16)
            {
                StringBuilder text = new StringBuilder();
                StringBuilder hex = new StringBuilder();
                hex.Append("|");

                for (int j = 0; j < 16; j++)
                {
                    if (j + i < end)
                    {
                        byte val = arr[j + i];
                        hex.Append(arr[j + i].ToString("X2"));
                        hex.Append(" ");
                        if (val >= 32 && val <= 127)
                        {
                            text.Append((char)val);
                        }
                        else
                        {
                            text.Append(".");
                        }
                    }
                    else
                    {
                        hex.Append("   ");
                        text.Append(" ");
                    }
                }
                hex.Append("|");
                hex.Append(text + "|");
                hex.AppendLine();
                hexDump.Append(hex.ToString());
            }

            hexDump.Append("-------------------------------------------------------------------");

            return hexDump.ToString();
        }
    }
}
